package com.midian.controller.user;

import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.midian.common.exception.BizException;
import com.midian.common.filter.annotation.Validate;
import com.midian.common.system.ErrorConstants;
import com.midian.common.system.RetManager;
import com.midian.common.system.SysStatic;
import com.midian.common.utils.CheckUtils;
import com.midian.common.utils.ContentJSONObject;
import com.midian.common.utils.DateHelper;
import com.midian.common.utils.PicUtils;
import com.midian.common.utils.StringUtil;
import com.midian.model.device.Device;
import com.midian.model.pic.Pic;
import com.midian.model.user.User;
import com.midian.service.device.IDeviceService;
import com.midian.service.sys.IValidateCodeService;
import com.midian.service.user.IUserService;

/**
 * 用户控制器
 * 
 */
@Controller("userController")
public class UserController {
	/** 日志 */
	private static Logger LOG = Logger.getLogger(UserController.class);
	/** 用户业务 */
	private IUserService userService;

	private IDeviceService deviceService;

	private IValidateCodeService validateCodeService;

	@Resource(name = "userService")
	public void setAdviceService(IUserService userService) {
		this.userService = userService;
	}

	@Resource(name = "deviceService")
	public void setDeviceService(IDeviceService deviceService) {
		this.deviceService = deviceService;
	}

	@Resource(name = "validateCodeService")
	public void setValidateCodeService(IValidateCodeService validateCodeService) {
		this.validateCodeService = validateCodeService;
	}

	PicUtils picUtils;

	@Resource(name = "picUtils")
	public void setPicUtils(PicUtils picUtils) {
		this.picUtils = picUtils;
	}

	/**
	 * 注册
	 * 
	 * @param client_key
	 * @param user_id
	 * @param access_token
	 * @param content
	 * @return
	 * @throws Exception
	 */
	@Validate(retCode = RetManager.common_register_error)
	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public @ResponseBody
	Object register(String client_key, String account, String password, String code, @RequestParam(required = false)MultipartFile head, @RequestParam(required = false) String name,
			@RequestParam(required = false) String sex, @RequestParam(required = false) String birthday, @RequestParam(required = false) String device_token) throws Exception {
		JSONObject json = new JSONObject();
		LOG.info("注册图片为"+head);
		try {
			// 检测手机号是否被注册
			if (this.userService.isExistUserByAccount(account)) {// 帐号已存在
				RetManager.getInstance().setRetError(json, RetManager.common_account_exist);
				return json;
			}
			// 生成用户记录
			User user = new User();
			user.setDelFlag(SysStatic.NORMALDELFLAG);
			user.setUserfrom(IUserService.USER_FROM_NORMAL); // 正常注册
			user.setIdentity(IUserService.IDENTITY_MEMBER); // 会员用户
			user.setAccount(account); // 帐号
			user.setPhone(account); // 电话号码
			user.setToken(StringUtil.generateToken(account));
			user.setTokenTime(new Date());
			user.setPassword(password); // 密码

			if (StringUtils.isNotBlank(name)) {
				user.setName(name);// 姓名
			}
			if (StringUtils.isNotBlank(birthday)) {
				user.setBirthday(DateHelper.parseDate("yyyy-MM-dd", birthday));
			}
			if (StringUtils.isNotBlank(sex)) {
				user.setSex(Integer.parseInt(sex));// 性别
			}

			if (head != null) {
				Pic pic = picUtils.uploadPic(head); // 头像
				if (pic != null) {
//					user.setHeadPic(pic);
					user.setHeadPicId(pic.getId());
				}
			}else {
				user.setHeadPicId("defaultHeadPic");
			}

			// 验证验证码
			if (!validateCodeService.isExistCodeAndDelete(account, code)) {
				RetManager.getInstance().setRetError(json, RetManager.common_validate_error);
				return json;
			}

			User u = this.userService.add(user);

			// 如果参数中包含设备号，更新用户的设备号信息
			updateDeviceToken(u, device_token, client_key);

			json.put("content", getUserContentJson(u));

		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		RetManager.getInstance().setRetSuccess(json, RetManager.common_register_success);

		return json;
	}

	/**
	 * 登录
	 * 
	 * @param client_key
	 * @param account
	 *            帐号
	 * @param password
	 *            密码
	 * @param device_token
	 *            设备号
	 * @return
	 */
	@Validate(retCode = RetManager.common_login_error)
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody
	Object login(String client_key, String account, String password, @RequestParam(required = false) String device_token,HttpServletRequest request) throws Exception {
		JSONObject json = new JSONObject();
		try {
			User user = this.userService.login(account, password);
			// 登录失败
			if (user == null) {
				RetManager.getInstance().setRetError(json, RetManager.common_account_or_passwd_error);
				return json;
			}
			// 用户已被删除 提示用户不可用
			if (SysStatic.DELFLAG.equals(user.getDelFlag())) {
				RetManager.getInstance().setRetError(json, RetManager.common_user_disable);
				return json;
			}
			
			// 更新设备号
			updateDeviceToken(user, device_token, client_key);
			// 更新access_token
			updateUserTokenForNormal(user);
			json.put("content", getUserContentJson(user));
		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		RetManager.getInstance().setRetSuccess(json, RetManager.common_login_success);

		return json;
	}

	/**
	 * 第三方登录
	 * 
	 * @param client_key
	 * @param third_id
	 *            第三方登录id
	 * @param user_from
	 *            来源（1：短信注册，2:微信，3:qq，4：新浪微博）
	 * @param device_token
	 *            设备号
	 * @param nickname
	 *            昵称
	 * @param headportrait
	 *            头像地址
	 * @return
	 */
	@Validate(retCode = RetManager.common_login_error)
	@RequestMapping(value = "/third_user_login", method = RequestMethod.POST)
	public @ResponseBody
	Object thirdLogin(String client_key, String third_id, String user_from, @RequestParam(required = false) String device_token, @RequestParam(required = false) String name,
			@RequestParam(required = false) String head , Integer sex,HttpServletRequest request) throws Exception {
		JSONObject json = new JSONObject();
		try {
			User targetUser = null;
			// 根据第三方登录id和来源查找用户
			User oldUser = this.userService.getUserByThirdIdAndFrom(third_id, Integer.parseInt(user_from));
			// 如果第三方登录用户已经存在，更新用户的Token信息
			if (oldUser != null) {
				// 如果用户已经被逻辑删除或禁用，提示错误信息
				if (SysStatic.DELFLAG.equals(oldUser.getDelFlag())) {
					RetManager.getInstance().setRetError(json, RetManager.common_user_disable);
					return json;
				}
				// 更新access_token
				updateUserTokenForThirdUser(oldUser);
				targetUser = oldUser; // 目标用户为旧用户
				
			} else {// 如果第三方登录用户未保存过，进行保存
				User user = new User();
				user.setThirdId(third_id); // 第三方登录id
				user.setUserfrom(Integer.parseInt(user_from)); // 用户来源
				user.setIdentity(IUserService.IDENTITY_MEMBER); // 会员用户
				user.setToken(StringUtil.generateToken()); // token
				user.setTokenTime(new Date()); // token时间
				user.setPassword(StringUtil.generatePassword(StringUtil.getRandomString(8))); // 密码
				user.setName(name); // 昵称
				user.setSex(sex);//性别 0：女 ， 1：男
				// 头像
				if (StringUtils.isNotBlank(head)) {
					Pic pic = picUtils.uploadPicByUrl(head);
					if (pic != null) {
//						user.setHeadPic(pic);
						user.setHeadPicId(pic.getId());
					}
				}
				this.userService.add(user); // 添加用户
				targetUser = user; // 目标用户为新添加的用户
				
			}
			// 如果参数中包含设备号，更新用户的设备号信息
			updateDeviceToken(targetUser, device_token, client_key);
			json.put("content", getUserContentJson(targetUser));
		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		RetManager.getInstance().setRetSuccess(json, RetManager.common_login_success);
		return json;
	}

	/**
	 * 验证原密码
	 * 
	 * @param client_key
	 * @param access_token
	 * @param user_id
	 *            用户ID
	 * @param pwd
	 *            原密码
	 * @return
	 * @throws BizException
	 */
	@Validate(retCode = RetManager.common_validate_error)
	@RequestMapping(value = "/validate_pwd", method = RequestMethod.GET)
	public @ResponseBody
	Object validatePwd(String client_key, String access_token, String user_id, String pwd, @RequestParam(required = false) User loginUser) throws BizException {
		JSONObject json = new JSONObject();
		try {
			User user = userService.get(user_id);
			if (user == null) {
				RetManager.getInstance().setRetError(json, RetManager.common_account_not_exist);
				return json;
			}
			if (!pwd.equals(user.getPassword())) {
				RetManager.getInstance().setRetError(json, RetManager.common_passwd_error);
				return json;
			}
			RetManager.getInstance().setRetSuccess(json, RetManager.common_verification_passed);
		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}

		return json;
	}

	/**
	 * 修改密码
	 * 
	 * @param client_key
	 * @param password
	 *            新密码
	 * @return
	 */
	@Validate(retCode = RetManager.common_change_error)
	@RequestMapping(value = "/update_pwd", method = RequestMethod.POST)
	public @ResponseBody
	Object updatePassword(String client_key, String access_token, String user_id, String pwd, String old_pwd) throws Exception {
		JSONObject json = new JSONObject();
		try {
			User user = userService.get(user_id);
			if (user == null) {
				RetManager.getInstance().setRetError(json, RetManager.common_account_not_exist);
				return json;
			}
			if (!old_pwd.equals(user.getPassword())) {
				RetManager.getInstance().setRetError(json, RetManager.common_passwd_error);
				return json;
			}

			// 更新用户密码
			int i = this.userService.updatePwdByUserId(user_id, pwd);
			if (i == 0) {
				RetManager.getInstance().setRetError(json, RetManager.common_change_fail);
				return json;
			}
		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		RetManager.getInstance().setRetSuccess(json, RetManager.common_change_success);
		return json;
	}

	/**
	 * 获取个人资料
	 * 
	 * @param client_key
	 * @param user_id
	 *            用户ID
	 * @param access_token
	 * @return
	 */
	@Validate(retCode = RetManager.common_error)
	@RequestMapping(value = "/user_detail", method = RequestMethod.GET)
	public @ResponseBody
	Object userDetail(String client_key, String access_token, String user_id, @RequestParam(required = false) User loginUser) throws Exception {
		JSONObject json = new JSONObject();
		// 根据用户id获取个人资料
		User user = userService.showUserDetail(user_id);
		if (user == null) {
			RetManager.getInstance().setRetError(json, RetManager.common_fail);
			return json;
		}
		json.put("content", getUserContentJson(user));
		return json;
	}

	/**
	 * 修改个人资料
	 * 
	 * @param client_key
	 * @param access_token
	 * @param user_id
	 * @param nickname
	 * @param sex
	 * @param head_pic
	 * @param loginUser
	 * @return
	 * @throws Exception
	 */
	@Validate(retCode = RetManager.common_change_error)
	@RequestMapping(value = "/update_user", method = RequestMethod.POST)
	public @ResponseBody
	Object updateUser(String client_key, String access_token, String user_id, @RequestParam(required = false) String name, @RequestParam(required = false) String sex,
			@RequestParam(required = false) MultipartFile head_pic, @RequestParam(required = false) User loginUser) throws Exception {
		JSONObject json = new JSONObject();
		User user = userService.get(user_id);
		try {
			if (head_pic != null) {// 有上传新的头像
				if (StringUtils.isNotBlank(user.getHeadPicId())) {// 原本有头像
					// 把旧的头像删除掉
					Pic pic = picUtils.updatePic(user.getHeadPicId(), head_pic);
					user.setHeadPicId(pic.getId());
				} else {// 直接增加用户头像
					Pic pic = picUtils.uploadPic(head_pic);
					user.setHeadPicId(pic.getId());
				}
			}
			if (StringUtils.isNotBlank(name)) {
				user.setName(name);// 昵称
			}
			if (StringUtils.isNotBlank(sex)) {
				user.setSex(Integer.parseInt(sex));// 性别
			}
			this.userService.updateUser(user);// 更新用户信息
		} catch (BizException e) {
			e.printStackTrace();
			LOG.error(e.getMessage());
			throw e;
		}
		json.put("content", getUserContentJson(user));
		RetManager.getInstance().setRetSuccess(json, RetManager.common_change_success);
		return json;
	}

	/**
	 * 修改手机号
	 * 
	 * @param client_key
	 * @param access_token
	 * @param user_id
	 * @param new_phone
	 * @param loginUser
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@Validate(retCode = RetManager.common_change_error)
	@RequestMapping(value = "/update_phone", method = RequestMethod.POST)
	public @ResponseBody
	Object updatePhone(String client_key, String access_token, String user_id, String new_phone, String code, @RequestParam(required = false) User loginUser) throws Exception {
		JSONObject json = new JSONObject();
		try {
			if (!this.validateCodeService.isExistCodeAndDelete(new_phone, code)) {
				RetManager.getInstance().setRetError(json, RetManager.common_verification_code_error);
				return json;
			}

			// 更新
			int i = this.userService.updatePhoneAndAccount(user_id, new_phone, new_phone);

			if (i == 0) {
				RetManager.getInstance().setRetError(json, RetManager.common_change_fail);
				return json;
			}

		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		RetManager.getInstance().setRetSuccess(json, RetManager.common_change_success);
		return json;
	}

	/**
	 * 找回密码
	 * 
	 * @param client_key
	 * @param phone
	 *            电话号码（帐号）
	 * @param pwd
	 *            密码
	 * @return
	 */
	@Validate(retCode = RetManager.common_error)
	@RequestMapping(value = "/find_pwd", method = RequestMethod.POST)
	public @ResponseBody
	Object findPassword(String client_key, String phone, String pwd, String code) throws Exception {
		JSONObject json = new JSONObject();
		try {
			// 验证验证码
			if (!validateCodeService.isExistCodeAndDelete(phone, code)) {
				RetManager.getInstance().setRetError(json, RetManager.common_validate_error);
				return json;
			}
			// 更新用户密码
			if (this.userService.updatePasswordByAccount(pwd, phone) == 0) {
				RetManager.getInstance().setRetError(json, RetManager.common_change_fail);
				return json;
			}
			RetManager.getInstance().setRetSuccess(json, RetManager.common_change_success);
		} catch (BizException e) {
			LOG.error(e.getMessage());
			throw e;
		}
		return json;
	}

	private void updateDeviceToken(User user, String device_token, String client_key) throws BizException {
		// 如果参数中包含设备号，更新用户的设备号信息
		if (StringUtils.isNotBlank(device_token)) {
			Device device = new Device();
			device.setUserId(user.getId()); // 设置用户id
			device.setDeviceToken(device_token); // 设置设备号
			device.setFrontType(CheckUtils.getClientKey(client_key));// 设置设备类型
			this.deviceService.saveOrUpdateDevice(device);
		}
	}

	private void updateUserTokenForNormal(User user) throws BizException {
		String token = StringUtil.generateToken(user.getAccount());
		// 更新用户的Token信息
		this.userService.updateUserTokenById(token, user.getId());
		user.setToken(token); // 设置用户的新token
	}

	private void updateUserTokenForThirdUser(User user) throws BizException {
		String token = StringUtil.generateToken(); // 生成新的token
		// 更新用户的Token信息
		this.userService.updateUserTokenById(token, user.getId());
		user.setToken(token); // 设置用户的新token
	}

	private JSONObject getUserContentJson(User user) {
		ContentJSONObject contentJson = new ContentJSONObject();
		contentJson.put("access_token", user.getToken());
		contentJson.put("user_id", user.getId());
		contentJson.put("name", user.getName());
		contentJson.put("head_pic", user.getHeadPicId());
		contentJson.put("phone", user.getPhone());
		contentJson.put("sex", user.getSex());
		contentJson.put("user_from", user.getUserfrom());
		return contentJson.getContent();
	}

}
